package org.coco.mvc.processor.impl;

import com.coco.entity.People;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.coco.core.annotation.ResponseBody;
import org.coco.mvc.DispatcherServlet;
import lombok.extern.slf4j.Slf4j;
import org.coco.mvc.RequestProcessorChain;

import org.coco.mvc.handle.GetHandleMapping;
import org.coco.mvc.handle.HandleMapping;
import org.coco.mvc.handle.PostHandleMapping;
import org.coco.mvc.interceptor.HandlerInterceptor;
import org.coco.mvc.processor.RequestProcessor;
import org.coco.mvc.render.impl.*;
import org.coco.util.ValidationUtil;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Controller请求处理
 */
@Slf4j
public class ControllerRequestProcessor implements RequestProcessor {

    private DispatcherServlet dispatcherServlet;

    private Map<String, HandleMapping> requestMappingMap;

    private List<Class<?>> interceptorList;

    private static final String AND_MARK = "&";
    private static final String EQUALS_MARK= "=";

    //该变量用来判断客户端请求有没有在requestMappingMap集合映射中存在
    private boolean MAPPING = false;

    private boolean isHaveMethod = false;

    public ControllerRequestProcessor(DispatcherServlet dispatcherServlet) {
        this.dispatcherServlet = dispatcherServlet;
        //获取所有的HandleMapping实例的集合映射
        this.requestMappingMap = dispatcherServlet.getRequestMappingMap();
        this.interceptorList = dispatcherServlet.getInterceptorList();
    }

    @Override
    public boolean process(RequestProcessorChain requestProcessorChain) throws Exception {
        try{
            //获取客户端请求的路径
            String requestPath = requestProcessorChain.getRequestPath();
            //开始对请求路径进行匹配
            for(String key : requestMappingMap.keySet()) {
                //对应上了请求的路径
                if(key.equalsIgnoreCase(requestPath)) {
                    MAPPING = true;
                    break;
                }
            }

            //说明客户端的请求有对应的方法
            boolean result = false;
            if(MAPPING) {
                //首先判断下有没有实现拦截器，如果有那么就要执行拦截器方法
                if(!ValidationUtil.isEmpty(interceptorList)) {
                    int length = interceptorList.size();
                    for(int i = 0; i < length; i ++) {
                        Class<? extends Class> aClass = interceptorList.get(i).getClass();
                        //获取到它的preHandle方法
                        HandlerInterceptor handlerInterceptor = (HandlerInterceptor) interceptorList.get(i).newInstance();
                        boolean returnValue = handlerInterceptor.preHandle(requestProcessorChain.getRequest(),requestProcessorChain.getResponse(),null);
                        if(!returnValue){
                            requestProcessorChain.setResultRender(new InternalErrorResultRender(new RuntimeException("拦截器不通过")));
                            return true;
                        }
                    }
                }
                //判断客户端请求的方法GET POST
                String requestMethod = requestProcessorChain.getRequestMethod();
                //如果是GET方法，那么在请求的URl上可能带有参数
                //如果请求带有参数,就需要进行解析
                String params = requestProcessorChain.getRequest().getQueryString();
                //在这里我们用一个局部的map存储key和value
                Map<String,Object> paramsMap = null;
                if("GET".equals(requestMethod)) {
                    //说明该get请求是携带了参数的
                    if(!ValidationUtil.isEmpty(params)) {
                        String[] paramsArray = params.split(AND_MARK);
                        paramsMap = new ConcurrentHashMap<>();
                        if(!ValidationUtil.isEmpty(paramsArray)) {
                            for(String str : paramsArray) {
                                String[] strings = str.split(EQUALS_MARK);
                                paramsMap.put(strings[0],strings[1]);
                            }
                        }
                    }
                    GetHandleMapping getHandleMapping = new GetHandleMapping();
                    result = getHandleMapping.doGet(requestMappingMap,requestPath,paramsMap,requestProcessorChain);
                }else if("POST".equals(requestMethod)){
                    PostHandleMapping postHandleMapping = new PostHandleMapping();
                    result = postHandleMapping.doPost(requestProcessorChain,requestMappingMap,requestPath);
                }

            }else {
                //说明客户端请求的资源不存在
                requestProcessorChain.setResultRender(new ResourceNotFoundResultRender());
                result = true;
            }
            MAPPING = false;
            return result;
        }catch (Exception e){
            log.error("server happen error " + e);
            requestProcessorChain.setResultRender(new InternalErrorResultRender(e));
        }
        return true;
    }

        private boolean isMethodName(Method method) {
            String methodName = method.getName();
            if(methodName.equals("wait") || methodName.equals("equals") ||
                    "toString".equals(methodName) || "hashCode".equals(methodName) ||
                    "getClass".equals(methodName) || "notify".equals(methodName) || "notifyAll".equals(methodName)) {
                return true;
            }
            return false;
        }

}
